File: //home/sioberen/www/cache/includes/related_products.php
<?php
/**
* ===================================================================
* RELATED PRODUCTS - DYNAMIC RENDER MODULE
* ===================================================================
* This module displays randomly fetched related products.
* It is dynamically populated by data prepared in `product.php`.
* It will not render a section if no related products are found.
*
* @var array $data The associative array containing all page details,
* including 'related_tools' and 'related_wanderer'.
* ===================================================================
*/
// Helper function to render a single product card.
// This keeps the main part of the template clean.
function render_related_product_card($product, $base_parasite_url) {
// Gracefully handle missing images
$images = array();
if (!empty($product['images'])) {
if (is_string($product['images'])) {
$images = explode(',', trim($product['images'], '{}'));
} elseif (is_array($product['images'])) {
$images = $product['images'];
}
}
$first_image = isset($images[0]) ? $images[0] : '//cdn.suruga-ya.jp/database/images/no_photo.jpg';
// Use the new, SEO-friendly URL format with the absolute base path and trailing slash for consistency.
$product_url = buildProductUrl($product['id'], isset($product['title']) ? $product['title'] : null);
$price = '$' . number_format((float)(isset($product['price']) ? $product['price'] : (isset($product['price_current']) ? $product['price_current'] : 0)), 2);
// Simulate rating for visual purposes, as it's not in the DB
$rating_score = rand(30, 50) / 10.0;
$rating_count = rand(5, 50);
// Build the HTML for one card
$card_html = '
<div class="related-product-card">
<a href="' . $product_url . '">
<div class="related-product-image">
<img src="' . htmlspecialchars($first_image) . '" alt="' . htmlspecialchars($product['title']) . '" loading="lazy">
</div>
<h2 class="related-product-title">' . htmlspecialchars($product['title']) . '</h2>
<div class="related-product-rating">
';
// Generate star icons based on the random rating
for ($i = 1; $i <= 5; $i++) {
$card_html .= '<span class="star">' . ($i <= floor($rating_score) ? '★' : '☆') . '</span>';
}
$card_html .= '
<span class="count">(' . $rating_count . ')</span>
</div>
<div class="related-product-price">' . htmlspecialchars($price) . '</div>
</a>
</div>';
return $card_html;
}
?>
<!-- Section for "Tools & equipment" -->
<?php if (!empty($data['related_tools'])): ?>
<div class="related-products-section">
<h3 class="related-products-header">Tools & equipment</h3>
<div class="related-products-grid">
<?php foreach ($data['related_tools'] as $product): ?>
<?php echo render_related_product_card($product, $data['base_parasite_url']); ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- Section for "Wanderer" -->
<?php if (!empty($data['related_wanderer'])): ?>
<div class="related-products-section">
<h3 class="related-products-header">Wanderer</h3>
<div class="related-products-grid">
<?php foreach ($data['related_wanderer'] as $product): ?>
<?php echo render_related_product_card($product, $data['base_parasite_url']); ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- Section 1: Products from the same leaf category -->
<?php if (!empty($data['leaf_category_products'])): ?>
<div class="related-products-section">
<h3 class="related-products-header"><?php echo htmlspecialchars($data['leaf_category']); ?></h3>
<div class="related-products-grid">
<?php foreach ($data['leaf_category_products'] as $product): ?>
<?php echo render_related_product_card($product, $data['base_parasite_url']); ?>
<?php endforeach; ?>
</div>
<div class="see-more-link">
<a href="<?php echo htmlspecialchars($data['random_link']); ?>">See the same product from <?php echo htmlspecialchars($data['leaf_category']); ?></a>
</div>
</div>
<?php endif; ?>
<!-- Section 2: Products from the same parent category -->
<?php if (!empty($data['parent_category_products'])): ?>
<div class="related-products-section">
<h3 class="related-products-header"><?php echo htmlspecialchars($data['parent_category']); ?></h3>
<div class="related-products-grid">
<?php foreach ($data['parent_category_products'] as $product): ?>
<?php echo render_related_product_card($product, $data['base_parasite_url']); ?>
<?php endforeach; ?>
</div>
<div class="see-more-link">
<a href="<?php echo htmlspecialchars($data['random_link']); ?>">See all the same products</a>
</div>
</div>
<?php endif; ?>
<!-- Section 3: Products from a random category -->
<?php if (!empty($data['random_category_products'])): ?>
<div class="related-products-section">
<h3 class="related-products-header"><?php echo htmlspecialchars($data['random_category_name']); ?></h3>
<div class="related-products-grid">
<?php foreach ($data['random_category_products'] as $product): ?>
<?php echo render_related_product_card($product, $data['base_parasite_url']); ?>
<?php endforeach; ?>
</div>
<div class="see-more-link">
<a href="<?php echo htmlspecialchars($data['random_link']); ?>">See all products from <?php echo htmlspecialchars($data['random_category_name']); ?></a>
</div>
</div>
<?php endif; ?>
<!-- Scoped CSS for the related products to avoid conflicts -->
<style>
.related-products-section {
margin-top: 40px;
}
.related-products-header {
font-size: 1.5rem;
font-weight: 500;
margin-bottom: 20px;
}
.related-products-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 16px;
}
@media (max-width: 1200px) {
.related-products-grid {
grid-template-columns: repeat(4, 1fr);
}
}
@media (max-width: 768px) {
.related-products-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 576px) {
.related-products-grid {
grid-template-columns: repeat(2, 1fr);
}
}
.related-product-card {
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 16px;
text-align: center;
transition: box-shadow 0.2s ease-in-out;
}
.related-product-card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
.related-product-card a {
text-decoration: none;
color: #111827;
}
.related-product-image img {
width: 100%;
height: 160px;
object-fit: contain;
margin-bottom: 16px;
}
.related-product-title {
font-size: 1rem;
line-height: 1.4;
font-weight: 400;
height: 2.8em; /* Clamp to 2 lines */
overflow: hidden;
margin-bottom: 10px;
}
.related-product-rating {
font-size: 0.9rem;
display: flex;
justify-content: center;
align-items: center;
}
.related-product-rating .star {
color: #f59e0b;
}
.related-product-rating .count {
color: #6b7280;
margin-left: 8px;
}
.related-product-price {
font-size: 1.125rem;
font-weight: 600;
color: #ef4444;
margin-top: 12px;
}
.see-more-link {
text-align: right;
margin-top: 16px;
}
.see-more-link a {
color: #337ab7;
text-decoration: underline;
}
</style>